/*==============================================
 * Task2c: Scenes & GUI's
 *
 * Written by <YOUR NAME HERE>
 *
 *==============================================*/

#include "GameUtils.h"
#include "GameEngine.h"
#include "Fail.h"
#include "SpriteUtils.h"
#include "FontUtils.h"
#include "XMesh.h"
#include "ConsoleOutput.h"
#include <sstream>

#include "SceneEngine.h"
#include "MessageBoxScene.h"

/** The game scene, featureing awesome gameplay.
Err, actually its waiting for you folks to add the gameplay
*/
class GameScene: public CScene
{
	CXMesh* mpGround;
	float mAngle;

	void Enter()
	{
		mTransOnTime=2;	// slow fade in
		mTransOffTime=2;	// slow fade out
		mpGround=new CXMesh(GetDevice(),"media/checker.x");
		SetupDefaultD3DOptions(GetDevice());
		mAngle=0;
	}
	void Update(float dt)
	{
		CScene::Update(dt);	// MUST CALL BASE CLASS'S Update
		if (IsTopMost()==false)	return;	// Pause if I'm not the topmost screen

		if (CGameWindow::KeyPress(VK_ESCAPE))
		{
			CMessageBoxScene* pMsg=new CMessageBoxScene("Quit?");
			pMsg->OnOkCloseScene(this);
			GetEngine()->AddScene(pMsg);
		}

		mAngle+=dt;
	}
	void Draw(float dt)
	{
		GetDevice()->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BLACK_COL, 1.0f, 0 );
		GetDevice()->BeginScene();

		D3DXMATRIX mat;
		D3DXMatrixRotationY(&mat,mAngle);
		mpGround->Draw(mat);

		DrawD3DFont(GetFont(),"TODO: add game here",50,50,YELLOW_COL);
		DrawD3DFont(GetFont(),"Press <escape> for main menu",0,400,CYAN_COL);


		DrawTransitionFade();	// fade, just add it before the EndScene
		GetDevice()->EndScene();
		// note: no need to call Present, that is done in the CSceneEngine
	}
	void Leave()
	{
		SAFE_DELETE(mpGround);
	}
};


/* location of the back button on the help scene
put here to make is accessible to Update & Draw function
*/
const POINT BACK_BUT={500,400};

/// the help scene.
/// displays instructions and a back button
class HelpScene: public CScene
{
	IDirect3DTexture9* mpButtonTex;
	ID3DXFont* mpFont;

	void Enter()
	{
		std::cout<<"HelpScene::enter\n";
		mTransOnTime=2;	// slow fade in
		mTransOffTime=2;	// slow fade out
		// load the media
		mpFont=CreateD3DFont(GetDevice(),"Arial",24,true);
		mpButtonTex=LoadSpriteTex(GetDevice(),"media/back_but.png");
	}
	void Update(float dt)
	{
		CScene::Update(dt);	// MUST CALL BASE CLASS'S Update
		if (IsTopMost()==false)	return;	// Pause if I'm not the topmost screen

		// WARNING: you cannot have two calls to KeyPress for the same key within a function
		// the second call always gives false
		// therefore one KeyPress with many tests within it
		if (CGameWindow::KeyPress(VK_LBUTTON))
		{
			POINT mouse=CGameWindow::GetMousePos();
			if (InSprite(mouse,BACK_BUT,mpButtonTex))	// clicked the button
			{
				ExitScene();
			}
		}
	}
	void Draw(float dt)
	{
		GetDevice()->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, YELLOW_COL, 1.0f, 0 );
		GetDevice()->BeginScene();

		GetSprite()->Begin(D3DXSPRITE_ALPHABLEND);
		// you can draw fonts with scaling & other effects using DrawD3DFontEx
		// but it must have a spitebatch set with D3DXSPRITE_ALPHABLEND
		DrawD3DFontEx(mpFont,GetSprite(),"Instructions",D3DXVECTOR2(100,0),
					   BLUE_COL,D3DXVECTOR2(0,0),3.0f);

		// just a normal draw using the spritebatch
		DrawSprite(GetSprite(),mpButtonTex,BACK_BUT);
		GetSprite()->End();

		DrawTransitionFade();	// fade, just add it before the EndScene
		GetDevice()->EndScene();
		// note: no need to call Present, that is done in the CSceneEngine
	}
	void Leave()
	{
		std::cout<<"HelpScene::Leave\n";
		SAFE_RELEASE(mpFont);
		SAFE_RELEASE(mpButtonTex);
	}
};


const POINT PLAY_BUT={100,400},
			HELP_BUT={300,400},
			EXIT_BUT={500,400};

/// the menu menu scene.
/// you know what this does....
class MenuScene: public CScene
{
	IDirect3DTexture9* mpButtonTex[3];
	IDirect3DTexture9* mpLogoTex;

	void Enter()
	{
		std::cout<<"MenuScene::enter\n";
		mTransOnTime=2;	// slow fade in
		mTransOffTime=2;	// slow fade out
		//TODO(load the media);
		mpLogoTex = LoadSpriteTex(GetDevice(),"media/logo.png");
		mpButtonTex[0] = LoadSpriteTex(GetDevice(),"media/play_but.png");
		mpButtonTex[1] = LoadSpriteTex(GetDevice(),"media/help_but.png");
		mpButtonTex[2] = LoadSpriteTex(GetDevice(),"media/exit_but.png");
	}
	void Update(float dt)
	{
		CScene::Update(dt);	// MUST CALL BASE CLASS'S Update
		if (IsTopMost()==false)	return;	// Pause if I'm not the topmost screen

		//TODO(MenuScene::Update);
		// you will need to detect the mouse clicks
		// using InSprite() from SpriteUtils
		// to go to a new scene you will need to 
		// GetEngine()->AddScene(new TheSceneClass());
		// you will also need to call ExitScene() when you want the menu to close
		if (CGameWindow::KeyPress(VK_LBUTTON))
		{
			POINT mouse=CGameWindow::GetMousePos();
			if (InSprite(mouse,PLAY_BUT,mpButtonTex[0]))	// clicked the button
			{
				GetEngine()->AddScene(new GameScene());
			}
			else if (InSprite(mouse,HELP_BUT,mpButtonTex[1]))
			{
				GetEngine()->AddScene(new HelpScene());
			}
			else if (InSprite(mouse,EXIT_BUT,mpButtonTex[2]))
			{
				ExitScene();
			}
		}
	}
	void Draw(float dt)
	{
		GetDevice()->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BLACK_COL, 1.0f, 0 );
		GetDevice()->BeginScene();

		//TODO(MenuScene::Draw);
		// textures must be within BeginScene()..EndScene
		// and within a SpriteBatches Begin..End
		// we need the D3DXSPRITE_ALPHABLEND to enable transparency
		// you need the background and three buttons
		// at PLAY_BUT,HELP_BUT & EXIT_BUT locations

		GetSprite()->Begin(D3DXSPRITE_ALPHABLEND);
		DrawSprite(GetSprite(),mpLogoTex,0,0,640,480);
		POINT mouse=CGameWindow::GetMousePos();
		float col[3];

		if (InSprite(mouse,PLAY_BUT,mpButtonTex[0]))
		{
			col[0] = 0.75f;
		}
		else
		{
			col[0] = 1.0f;
		}
		if (InSprite(mouse,HELP_BUT,mpButtonTex[1]))
		{
			col[1] = 0.75f;
		}
		else
		{
			col[1] = 1.0f;
		}
		if (InSprite(mouse,EXIT_BUT,mpButtonTex[2]))
		{
			col[2] = 0.75f;
		}
		else
		{
			col[2] = 1.0f;
		}

		DrawSprite(GetSprite(),mpButtonTex[0],PLAY_BUT,col[0] * WHITE_COL);
		DrawSprite(GetSprite(),mpButtonTex[1],HELP_BUT,col[1] * WHITE_COL);
		DrawSprite(GetSprite(),mpButtonTex[2],EXIT_BUT,col[2] * WHITE_COL);
		GetSprite()->End();
		
		DrawTransitionFade();// fade, just add it before the EndScene
		GetDevice()->EndScene();
		// note: no need to call Present, that is done in the CSceneEngine
	}
	void Leave()
	{
		std::cout<<"MenuScene::Leave\n";
		SAFE_RELEASE(mpLogoTex);
		for(int i=0;i<3;i++)
			SAFE_RELEASE(mpButtonTex[i]);
	}
};


int WINAPI WinMain(HINSTANCE hInstance, 
				   HINSTANCE hPrevInstance, 
				   LPTSTR lpCmdLine, int nCmdShow)
{
    ENABLE_LEAK_DETECTION();	// Enable run-time memory check for debug builds.
	CSceneEngine eng(640,480,false);
	eng.AddScene(new MenuScene());
	return eng.Go(hInstance);	// runs everything
}
